# Forecast generator sourcing Weather Underground. WU has a pretty extensive
# API that outputs to JSON as well as XML; this uses JSON as that's really
# easy to import.
# API docs: http://www.wunderground.com/weather/api/d/documentation.html
# API limits on "Developer" key: 500 calls/day, 10 calls/minute. The latter
# might be an issue when lots of locations are configured.

import datetime
import json
import logging
import urllib.request

from forecasts import common

class ForecastGen(common.ForecastGen):
    shortname = 'wunderground'
    _baseurl = 'http://api.wunderground.com/\
api/{key}/forecast10day/q/{lat:f},{lon:f}.json'

    def generate_url(self, latitude, longitude):
        with open('apikeys/wunderground.key') as keyfile:
            apikey = keyfile.read().strip()
        self.url = self._baseurl.format(
            key=apikey, 
            lat=float(latitude), 
            lon=float(longitude))
        self.log.debug('URL: ' + self.url)

    def fetchdata(self, url=None):
        """Fetches the data from the web. 

        Returns a format suitable for use in processdata().
        """
        if url == None:
            url = self.url
        with urllib.request.urlopen(url) as f:
            data = json.loads(f.read().decode('utf-8'))
        return data

    def processdata(self, data):
        """data: a dictionary-ish thing as generated by json.loads()

        This is the one function that heavily depends on the json input being 
        as expected.
        """
        forecasts = {}
        for day in data['forecast']['simpleforecast']['forecastday']:
            # period is 1-based on today
            datestring = '{year}{month}{day}'.format(**day['date'])
            format = '%Y%m%d'
            thatday = datetime.datetime.strptime(datestring, format).date()
            # The feed does not provide "today" in local time - or at all - so
            # we'll construct it here.
            today = thatday - datetime.timedelta(day['period']-1)
            forecasts[day['period'] - 1] = common.Forecast(
                today,
                thatday,
                int(day['low']['celsius']),
                int(day['high']['celsius']))
        self.log.debug('Extracted {0} forecasts from the feed'.format(
            len(forecasts)))
        return forecasts

if __name__ == '__main__':
    logging.basicConfig(format='%(levelname)s-%(name)s: %(message)s', level=logging.DEBUG)
    gen = ForecastGen(-37.02, 174.8)
    print(gen.getforecast(1))
    print(gen.getforecast(2))
    print(gen.getforecast(3))
